import { JavascriptGenerator, javascriptGenerator } from "blockly/javascript";
import { Tanslate } from "./translate";
import * as Blockly from 'blockly/core';
import { getValue } from "./com";
export namespace WebCanvas {
    const blocks = [
        {
            "key": "get_context",
            "message0": "%{from} %1 %{get_context}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "canvas",
                    "check": "element"
                },
            ],
            "output": "canvas_context",
            "colour": 190
        },
        {
            "key": "draw_image",
            "message0": "%1 %{draw}%{image} %2  x %3  y %4  %{element_width} %5  %{element_height} %6",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "img",
                    "check": "element"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "width",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "height",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "draw_image_crop",
            "message0": "%1 %{draw}%{image} %2 sx %3 sy %4 %{source_width} %5 %{source_height} %6 x %7 y %8 %{element_width} %9 %{element_height} %10",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "img",
                    "check": "element"
                },
                {
                    "type": "input_value",
                    "name": "sx",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "sy",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "swidth",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "sheight",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "width",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "height",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_stroke",
            "message0": "%1 %{ctx_stroke}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "colour": 190
        },
        {
            "key": "set_stroke_style",
            "message0": "%1 %{set_stroke_style} %{ctx_line_width} %2 %{colors} %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "width",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "color",
                    "check": "Colour"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_fill",
            "message0": "%1 %{ctx_fill}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "colour": 190
        },
        {
            "key": "set_fill_style",
            "message0": "%1 %{set_fill_style} %{colors} %2",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "color",
                    "check": "Colour"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_rect",
            "message0": "%1 %{ctx_rect} x %2 y %3 %{width} %4 %{height} %5 %{ctx_radii} %6",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "width",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "height",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "radius",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_clear_rect",
            "message0": "%1 %{ctx_clear_rect} x %2 y %3 %{width} %4 %{height} %5",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "width",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "height",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_arc",
            "message0": "%1 %{ctx_arc} x %2 y %3 %{radius} %4 %{ctx_startAngle} %5 %{ctx_endAngle} %6",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "radius",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "startAngle",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "endAngle",
                    "check": "Number"
                }

            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_restore",
            "message0": "%1 %{ctx_restore}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "colour": 190
        },
        {
            "key": "ctx_save",
            "message0": "%1 %{ctx_save}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "colour": 190
        },
        {
            "key": "ctx_rotate",
            "message0": "%1 %{ctx_rotate} %2",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "value",
                    "check": "Number"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_scale",
            "message0": "%1 %{ctx_scale} x %2 y %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_translate",
            "message0": "%1 %{ctx_translate} x %2 y %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_begin_path",
            "message0": "%1 %{ctx_begin_path}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "colour": 190
        },
        {
            "key": "ctx_close_path",
            "message0": "%1 %{ctx_close_path}",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                }
            ],
            "nextStatement": null,
            "previousStatement": null,
            "colour": 190
        },
        {
            "key": "ctx_move_to",
            "message0": "%1 %{ctx_move_to} x %2 y %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_line_to",
            "message0": "%1 %{ctx_line_to} x %2 y %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_draw_text",
            "message0": "%1 %2 %{text} %3 x %4 y %5",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "field_dropdown",
                    "name": "type",
                    "options": [
                        ["%{strokeText}", "strokeText"],
                        ["%{fillText}", "fillText"]
                    ]
                },
                {
                    "type": "input_value",
                    "name": "text",
                    "check": "String"
                },
                {
                    "type": "input_value",
                    "name": "x",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "y",
                    "check": "Number"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "ctx_set_font",
            "message0": "%1 %{set} %{element_font_size} %2 %{element_font_family} %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "ctx",
                    "check": "canvas_context"
                },
                {
                    "type": "input_value",
                    "name": "size",
                    "check": "Number"
                },
                {
                    "type": "field_input",
                    "name": "font",
                    "text": "Arial"
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "to_img_url",
            "message0": "%1 %{to_img_url} %{type} %2 %{img_quality} %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "canvs",
                    "check": "element"
                },
                {
                    "type": "field_dropdown",
                    "name": "type",
                    "options": [
                        ["png", "image/png"],
                        ["jpg", "image/jpeg"],
                        ["webp", "image/webp"],
                    ]
                },
                {
                    "type": "field_number",
                    "name": "encoderOptions",
                    "value": 0.9,
                    "min": 0,
                    "max": 1,
                },
            ],
            "output": "String",
            "inputsInline": true,
            "colour": 190
        },
        {
            "key": "request_animation_frame",
            "message0": "%{request_animation_frame} \n %1",
            "args0": [
                {
                    'type': 'input_statement',
                    'name': 'body0',
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            "tooltip": '%{request_animation_frame_tips}',
            "colour": 360
        },
    ]

    export function init() {
        initGenerator()
        Tanslate.tr(blocks).forEach((item: any) => {
            Blockly.Blocks[item.key] = {
                init: function (this: any) {
                    this.jsonInit(item);
                }
            }
        })
    }

    export function getTools() {
        const netBlocks = {
            kind: 'category',
            name: Blockly.Msg['canvas'],
            "colour": 190,
            contents: [] as any[]
        }
        blocks.forEach((item: any) => {
            netBlocks.contents.push({
                kind: 'block',
                type: item.key
            })
        })

        return netBlocks
    }

    function initGenerator() {
        javascriptGenerator.forBlock['get_context'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const canvas = getValue(block, generator, 'canvas');
            return `${canvas}.getContext('2d')`;
        }
        javascriptGenerator.forBlock['draw_image'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const img = getValue(block, generator, 'img');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            const width = getValue(block, generator, 'width');
            const height = getValue(block, generator, 'height');
            if (!img || !x || !y || !width || !height) {
                throw new Error(block.id);
            }
            return `${ctx}.drawImage(${img}, ${x}, ${y}, ${width}, ${height});\n`;
        }

        javascriptGenerator.forBlock['draw_image_crop'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const img = getValue(block, generator, 'img');
            const sx = getValue(block, generator, 'sx');
            const sy = getValue(block, generator, 'sy');
            const swidth = getValue(block, generator, 'swidth');
            const sheight = getValue(block, generator, 'sheight');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            const width = getValue(block, generator, 'width');
            const height = getValue(block, generator, 'height');
            if (!img || !sx || !sy || !swidth || !sheight || !x || !y || !width || !height) {
                throw new Error(block.id);
            }
            return `${ctx}.drawImage(${img}, ${sx}, ${sy}, ${swidth}, ${sheight}, ${x}, ${y}, ${width}, ${height});\n`;
        }

        javascriptGenerator.forBlock['ctx_stroke'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.stroke();\n`;
        }

        javascriptGenerator.forBlock['set_stroke_style'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const width = getValue(block, generator, 'width');
            const color = getValue(block, generator, 'color');
            if (!ctx || !width || !color) {
                throw new Error(block.id);
            }
            return `${ctx}.strokeStyle = ${color};\n ${ctx}.lineWidth = ${width};\n`;
        }

        javascriptGenerator.forBlock['ctx_stroke'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.stroke();\n`;
        }

        javascriptGenerator.forBlock['ctx_fill'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.fill();\n`;
        }

        javascriptGenerator.forBlock['set_fill_style'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const color = getValue(block, generator, 'color');
            if (!ctx || !color) {
                throw new Error(block.id);
            }
            return `${ctx}.fillStyle = ${color};\n`;
        }

        javascriptGenerator.forBlock['ctx_arc'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            const radius = getValue(block, generator, 'radius');
            const startAngle = getValue(block, generator, 'startAngle');
            const endAngle = getValue(block, generator, 'endAngle');
            if (!ctx || !x || !y || !radius || !startAngle || !endAngle) {
                throw new Error(block.id);
            }
            return `${ctx}.arc(${x}, ${y}, ${radius}, ${startAngle}, ${endAngle});\n`;
        }

        javascriptGenerator.forBlock['ctx_restore'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.restore();\n`;
        }

        javascriptGenerator.forBlock['ctx_save'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.save();\n`;
        }

        javascriptGenerator.forBlock['ctx_rotate'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const value = getValue(block, generator, 'value');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.rotate(${value});\n`;
        }

        javascriptGenerator.forBlock['ctx_scale'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            if (!ctx || !x || !y) {
                throw new Error(block.id);
            }
            return `${ctx}.scale(${x}, ${y});\n`;
        }

        javascriptGenerator.forBlock['ctx_translate'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            if (!ctx || !x || !y) {
                throw new Error(block.id);
            }
            return `${ctx}.translate(${x}, ${y});\n`;
        }

        javascriptGenerator.forBlock['ctx_rect'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            const width = getValue(block, generator, 'width');
            const height = getValue(block, generator, 'height');
            const radiius = getValue(block, generator, 'radius');
            if (!ctx || x === undefined || y === undefined || width === undefined || height === undefined) {
                throw new Error(block.id);
            }
            return `${ctx}.roundRect(${x}, ${y}, ${width}, ${height}, ${radiius});\n`;
        }

        javascriptGenerator.forBlock['ctx_clear_rect'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            const width = getValue(block, generator, 'width');
            const height = getValue(block, generator, 'height');
            if (!ctx || !x || !y || !width || !height) {
                throw new Error(block.id);
            }
            return `${ctx}.clearRect(${x}, ${y}, ${width}, ${height});\n`;
        }

        javascriptGenerator.forBlock['ctx_begin_path'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.beginPath();\n`;
        }

        javascriptGenerator.forBlock['ctx_close_path'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            if (!ctx) {
                throw new Error(block.id);
            }
            return `${ctx}.closePath();\n`;
        }

        javascriptGenerator.forBlock['ctx_move_to'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            if (!ctx || !x || !y) {
                throw new Error(block.id);
            }
            return `${ctx}.moveTo(${x}, ${y});\n`;
        }

        javascriptGenerator.forBlock['ctx_line_to'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            if (!ctx || !x || !y) {
                throw new Error(block.id);
            }
            return `${ctx}.lineTo(${x}, ${y});\n`;
        }

        javascriptGenerator.forBlock['ctx_draw_text'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const type = getValue(block, generator, 'type');
            const text = getValue(block, generator, 'text');
            const x = getValue(block, generator, 'x');
            const y = getValue(block, generator, 'y');
            if (!ctx || !text || !x || !y) {
                throw new Error(block.id);
            }
            return `${ctx}.${type}(${text},${x}, ${y});\n`;
        }

        javascriptGenerator.forBlock['ctx_set_font'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ctx = getValue(block, generator, 'ctx');
            const font = getValue(block, generator, 'font');
            const size = getValue(block, generator, 'size');
            if (!ctx || !size) {
                throw new Error(block.id);
            }
            return `${ctx}.font = '${size}px ${font || ''}';\n`;
        }

        javascriptGenerator.forBlock['to_img_url'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const canvs = getValue(block, generator, 'canvs');
            const type = block.getFieldValue('type');
            const tp = block.getFieldValue('encoderOptions');
            if (!canvs || type === undefined || tp === undefined) {
                throw new Error(block.id);
            }
            return `${canvs}.toDataURL('${type}', ${tp});\n`;
        }

        javascriptGenerator.forBlock['request_animation_frame'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('body0');
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            return `requestAnimationFrame(() => {${lines}});\n`;
        }
    }
}